function showTips(txt,time,status){  
    var htmlCon = '';  
    if(txt != ''){
        if(status == 1 || status == undefined){  //info
            htmlCon = '<div class="tipsBox" style="width:220px;padding:10px;background-color:#4AAF33;border-radius:4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;color:#fff;box-shadow:0 0 3px #ddd inset;-webkit-box-shadow: 0 0 3px #ddd inset;text-align:center;position:fixed;top:25%;left:50%;z-index:999999;margin-left:-120px;"><i class="glyphicon glyphicon-info-sign"></i>&nbsp;'+txt+'</div>';  
        } else if (status == 2) {  //warning
            htmlCon = '<div class="tipsBox" style="width:220px;padding:10px;background-color:#b09413;border-radius:4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;color:#fff;box-shadow:0 0 3px #ddd inset;-webkit-box-shadow: 0 0 3px #ddd inset;text-align:center;position:fixed;top:25%;left:50%;z-index:999999;margin-left:-120px;"><i class="glyphicon glyphicon-warning-sign"></i>&nbsp;'+txt+'</div>';  
        } else if (status == 3) {  //error
            htmlCon = '<div class="tipsBox" style="width:220px;padding:10px;background-color:#D84C31;border-radius:4px;-webkit-border-radius: 4px;-moz-border-radius: 4px;color:#fff;box-shadow:0 0 3px #ddd inset;-webkit-box-shadow: 0 0 3px #ddd inset;text-align:center;position:fixed;top:25%;left:50%;z-index:999999;margin-left:-120px;"><i class="glyphicon glyphicon-remove-circle"></i>&nbsp;'+txt+'</div>';  
        }
        $('body').prepend(htmlCon);  
        if(time == '' || time == undefined){
            time = 1500;   
        }  
        setTimeout(function(){ $('.tipsBox').remove(); },time);  
    }  
}
function alertErr(title, msg, cb) {
    //showTips(msg, 5000, 3);
    swal({
        "title": title ||'',
        "text": msg || '',
        "html": true,
        "type": "error"
    }, cb);

}
function alertWarn(title, msg, cb) {
    //showTips(msg, 4000, 2);
    swal({
        "title": title ||'',
        "text": msg || '',
        "html": true,
        "type": "warning"
    }, cb);
}
function alertInfo(title, msg, cb) {
    //showTips(msg, 3000, 1);
    swal({
        "title": title ||'',
        "text": msg || '',
        "html": true,
        "type": "info"
    }, cb);
}
function confirm(type, title, text, okText, cancelText, cb) {
    swal({
        title: title || '',
        text: text || '',
        type: type || "info",
        showCancelButton: cancelText ? true : false,
        confirmButtonColor: "#DD6B55",
        confirmButtonText: okText || 'OK',
        cancelButtonText: cancelText || 'Cancel'
    },
    cb);
}

toastr.options.closeButton=true;
toastr.options.positionClass="toast-bottom-right";
function msg(msg) {
    //showTips(msg, 3000, 1);
    toastr.success(msg);
}
function msgWarning(msg) {
    toastr.warning(msg);
}
function msgErr(msg) {
    //showTips(msg, 5000, 3);
    if (!window.needRelogin) toastr.error(msg);
}
function modalDialog(args) {
    modalAlert(args.type, args.title, args.text, args.ok, args.cancel, args.callback, args.icon);
}
function modalAlert(type, title, text, ok, cancel, callback, icon){
    /*swal({
     title: title || '',
     text: text || '',
     type: type || "info",
     showCancelButton: cancel || false,
     confirmButtonColor: "#4b94dd",
     confirmButtonText: ok || 'OK',
     cancelButtonText: cancel || 'Cancel'
     },
     callback);*/
    if (typeof(bootbox)!='undefined') {
        var options = {
            'title' : title || '',
            'message' : text || '',
            'onEscape' : true,
            'buttons' : {}
        };
        if (ok) options.buttons.ok = {
            'label': ok || i18nindex.ok || 'OK',
            'className': 'btn-success',
            'callback' : function(){
                alertModal.find('.btn-success').attr('disabled','disabled');
                typeof(callback)=='function' && callback();
            }
        };
        if (cancel) options.buttons.cancel = {
            label: cancel || i18nindex.cancel || 'Cancel',
            className: 'btn-default'
        };
        var alertModal = bootbox.dialog(options).on('shown.bs.modal', function() {
            var hdbgcolor = "#2c8bfb", hdcolor = 'white';
            if (type=='warning') {
                hdbgcolor = "#f1b71f", hdcolor = 'white';
            } else if (type=='error') {
                hdbgcolor = "red";
            }
            alertModal.find('.modal-header').css({"backgroundColor":hdbgcolor, 'color':hdcolor});
        });
    } else {
        $(document.body).append('<div class="tipModal modal fade" tabindex="-1" role="dialog" aria-hidden="true">' +
            '<div class="modal-dialog"><div class="modal-content">' +
            '<div class="modal-header" style="background-color: #2c8bfb;color:white;">' +
            '<h4 class="modal-title"><i class="' + (icon || 'fa fa-check') + '"></i><span class="modal-title-text"></span></h4></div><div class="modal-body"></div><div class="modal-footer">' +
            '<button type="button" class="btn btn-success" data-dismiss="modal"></button>' +
            '<button type="button" class="btn btn-default" data-dismiss="modal"></button>' +
            '</div></div></div></div>'
        );
        var tipModal = $('.tipModal:last');
        tipModal.find('.btn-success').unbind('click');
        tipModal.find('.btn-default').unbind('click');
        var hdcolor = "#2c8bfb";
        if (type == 'warning') {
            hdcolor = "#f1b71f";
        } else if (type == 'error') {
            hdcolor = "red";
        }
        tipModal.find('.modal-header').css("backgroundColor", hdcolor);
        tipModal.find('.modal-title-text').html(title || '');
        tipModal.find('.modal-body').html(text || '');
        if (ok) {
            tipModal.find('.btn-success').html(ok).show();
        } else {
            tipModal.find('.btn-success').hide();
        }
        if (cancel) {
            tipModal.find('.btn-default').html(cancel).show();
        } else {
            tipModal.find('.btn-default').hide();
        }
        ok && typeof(callback) == 'function' && tipModal.find('.btn-success').click(function () {
            $(this).attr('disabled', 'disabled');
            tipModal.modal('hide');
            callback()
        });
        tipModal.modal().on('hidden.bs.modal', function () {
            tipModal.remove();
        });
    }
}

Array.prototype.filter = function(callback) {
    var rs = [];
    for ( var i = 0, length = this.length; i < length; i++ ) {
        if (callback(this[i], i)) {
            rs.push(this[i]);
        }
    }
    return rs;
};

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position){
        position = position || 0;
        return this.substr(position, searchString.length) === searchString;
    };
}

$(document).ajaxComplete(function(e, req) {
    fm_checkSession(e, req, null);
});
// $.ajaxError(function(xhr, textstate, errthr) {
//     msgErr("错误Error: [" + textstate + "]: " + errthr)
// });
$(document).ajaxStart(function(){
    typeof(Metronic)!='undefined' && Metronic.blockUI({overlayColor: 'gray',animate:true});
});
$(document).ajaxStop(function(){
    setTimeout(function(){typeof(Metronic)!='undefined' && Metronic.unblockUI();},100);
});

function doGetAsyncJson(url, callbackFunc, errFunc) {
    return jQuery.ajax({
        url: encodeURI(url),
        async: true,
        cache: false,
        type: "GET",
        dataType: "json",
        success: function(_data) {
            if (typeof(callbackFunc) == "function") {
                callbackFunc(_data)
            }
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    })
}
function doPostAsyncJson(url, inputData, callbackFunc, errFunc) {
    return jQuery.ajax({
        url: encodeURI(url),
        async: true,
        cache: false,
        type: "POST",
        data: inputData,
        dataType: "json",
        success: function(_data) {
            if (typeof(callbackFunc) == "function") {
                callbackFunc(_data)
            }
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    })
}
function doGetSyncJson(url, inputData, errFunc) {
    var rtndata = null;
    var args = {
        url: encodeURI(url),
        async: false,
        cache: false,
        type: "GET",
        dataType: "json",
        success: function(data) {
            rtndata = data
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    };
    inputData && (args.data = inputData);
    jQuery.ajax(args);
    return rtndata
}
function doPostSyncJson(url, inputData, errFunc) {
    var rtndata = null;
    $.ajax({
        contentType: 'application/x-www-form-urlencoded',
        url: encodeURI(url),
        async: false,
        cache: false,
        type: "POST",
        data: inputData,
        dataType: "json",
        success: function(data) {
            rtndata = data
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    });
    return rtndata
}
function doDeleteSyncJson(url, errFunc) {
    var rtndata = null;
    $.ajax({
        url: encodeURI(url),
        async: false,
        cache: false,
        type: "DELETE",
        dataType: "json",
        success: function(data) {
            rtndata = data
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    });
    return rtndata
}
function doDeleteAsyncJson(url, callback, errFunc) {
    return $.ajax({
        url: encodeURI(url),
        async: true,
        cache: false,
        type: "DELETE",
        dataType: "json",
        success: function(data) {
            typeof(callback)=='function' && callback(data);
        },
        //complete: fm_checkSession,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    });
}

//cross domain
function doGetAsyncJsonp(url, callback, errFunc) {
    url = url.replace(/jsoncallback=\?/g,'test=test');
    //console.log(url);
    var args = {
        url: url,
        async: true,
        cache: false,
        type: "GET",
        dataType: "json",
        success: callback,
        //complete: fm_checkSessionJsonp,
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                console.error("Error: accessing "+url+" <br/>[" + textstate + "]: " + errthr);
                msgErr("Error: accessing "+url+" [" + textstate + "]: " + errthr)
            }
    };
    return jQuery.ajax(args);
}

function fm_checkSession(e, req, txt) {
    var relogin = false;
    if (req.readyState == 4 && req.getResponseHeader('Content-Type') && req.responseText) {
        if (req.getResponseHeader('Content-Type').indexOf('json') > -1 && req.getResponseHeader('x-meta') == "META_DESC_LOGIN") {
            relogin = true;
        } else if (req.getResponseHeader('Content-Type').indexOf('html') > -1 && req.responseText.indexOf("META_DESC_LOGIN") > -1) {
            relogin = true;
        }
    }
    if (relogin) {
        window.needRelogin = true;
        if (typeof(window.top.onSessionTimeout) == 'function') {
            window.top.needRelogin = true;
            window.top.onSessionTimeout(); return;
        } else if (window.parent && typeof(window.parent.onSessionTimeout) == 'function') {
            window.parent.needRelogin = true;
            window.parent.onSessionTimeout(); return;
        }
        //window.top.location.href='/';
        window.top.location.reload();
    }
}

function openWindowByUrl(_id, _url) {
    var a1new = document.createElement("a");
    a1new.setAttribute("href", _url);
    a1new.setAttribute("target", "_blank");
    a1new.setAttribute("id", "openwin_" + _id);
    document.body.appendChild(a1new);
    a1new.click()
}
function waitstart(msg) {
    $(".waitMsg").html((msg || "") + fmd_i18n_msg_wait);
    $(".wait").show()
}
function waitend() {
    $(".wait").hide();
    $(".waitMsg").html('')
}
function changeicosize(_img, enlarge) {
    if (enlarge) {
        _img.width = 22;
        _img.height = 22
    } else {
        _img.width = 18;
        _img.height = 18
    }
}
function getMousePos(event) {
    var e = event || window.event;
    var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
    var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
    var x = e.pageX || e.clientX + scrollX;
    var y = e.pageY || e.clientY + scrollY;
    return {
        'x': x,
        'y': y
    }
}
function loadModule(lang, modulePath, module) {
    loadJsFile(modulePath + '/' + module + '/i18n_' + lang + '.js');
    loadJsFile(modulePath + '/' + module + '/prop.js')
}
function loadModuleAsync(lang, modulePath, module) {
    return loadJsFile(modulePath + '/' + module + '/i18n_' + lang + '.js', true).then(loadJsFile(modulePath + '/' + module + '/prop.js', true));
}
function loadJsFile(filename, async) {
    return jQuery.ajax({
        url: filename,
        async: !! async,
        cache: true,
        type: "GET",
        dataType: "script",
        error: (typeof(errFunc) == "function") ? errFunc : function(xhr, textstate, errthr) {
                msgErr("Error: [" + textstate + "]: " + errthr)
            }
    })
}
function loadCssFile(filename, filetype) {
    var fileref = document.createElement('link');
    fileref.setAttribute("rel", "stylesheet");
    fileref.setAttribute("type", "text/css");
    fileref.setAttribute("href", filename);
    document.getElementsByTagName("head")[0].appendChild(fileref)
}

function closeWin() {
    if ( window.opener && typeof (window.opener.funcRefreshOnChildWinClose) == "function" ) {
        try {
            window.opener.funcRefreshOnChildWinClose();
        } catch(e){console.log('error calling window.opener.funcRefreshOnChildWinClose.'+e)}
    } else if ( window.parent && typeof (window.parent.funcRefreshOnChildWinClose) == "function" ) {
        try {
            window.parent.funcRefreshOnChildWinClose();
        } catch(e){console.log('error calling window.parent.funcRefreshOnChildWinClose.'+e)}
    }
    if (window.opener) {
        if (navigator.appName == 'Microsoft Internet Explorer') {
            window.opener = 'whatever';
            window.open('', '_parent', '');
            window.close()
        } else {
            window.open('', '_self', '');
            window.close()
        }
    } else {
        if (navigator.appName == 'Microsoft Internet Explorer') {
            window.opener = null;
            window.open('', '_self', '');
            window.close()
        } else {
            //window.location.href = "about:blank";
            window.opener = null;
            window.open('','_self','');
            window.close();
            setTimeout(function(){window.location.href="about:blank";},100);
        }
    }
}

//formatDate("yyyy-MM-dd");
//formatDate("yyyy-MM-dd hh:mm:ss");
function formatDate(d, fmt) {
    if (!d) return '';
    var o = {
        "M+": d.getMonth() + 1, //月份
        "d+": d.getDate(), //日
        "h+": d.getHours(), //小时
        "m+": d.getMinutes(), //分
        "s+": d.getSeconds(), //秒
        "q+": Math.floor((d.getMonth() + 3) / 3), //季度
        "S": d.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (d.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

function formatDateLocal(d, fmt) {
    if (d==null) return '';
    if (typeof(d)=='string') d = new Date(d);
    d.setTime(d.getTime()-(60000*d.getTimezoneOffset()));
    return formatDate(d, fmt);
}

function formatDateLocalZh(d) {
    return formatDateLocal(d, 'yyyy-MM-dd hh:mm:ss');
}

var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function base64encode(str) {
    var out, i, len;
    var c1, c2, c3;

    len = str.length;
    i = 0;
    out = "";
    while(i < len) {
        c1 = str.charCodeAt(i++) & 0xff;
        if(i == len)
        {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt((c1 & 0x3) << 4);
            out += "==";
            break;
        }
        c2 = str.charCodeAt(i++);
        if(i == len)
        {
            out += base64EncodeChars.charAt(c1 >> 2);
            out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
            out += base64EncodeChars.charAt((c2 & 0xF) << 2);
            out += "=";
            break;
        }
        c3 = str.charCodeAt(i++);
        out += base64EncodeChars.charAt(c1 >> 2);
        out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
        out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
        out += base64EncodeChars.charAt(c3 & 0x3F);
    }
    return out;
}

var MyUtilJs = {};

MyUtilJs.getJsonKeyLength = function(obj) {
    var count = 0;
    if ('object'==typeof(obj) && obj && obj.length==undefined) {
        for (var i in obj) {
            count ++;
        }
    }
    return count;
};

MyUtilJs.isEmpty = function(obj) {
    if (!obj) return true;
    for (var i in obj) {
        return false;
    }
    return true;
};

//deep copy
MyUtilJs.copyObj = function(obj) {
    if (!obj) return null;
    if (typeof(obj) != 'object') return obj;
    var newobj = obj instanceof Array ? [] : {};
    for (var i in obj) {
        if (typeof(obj[i]) == 'object') newobj[i] = MyUtilJs.copyObj(obj[i]);
        else newobj[i] = obj[i];
    }
    return newobj;
};

//check equal
MyUtilJs.isEqual = function(a, b) {
    if (!a && !b) {
        return true;
    } else if ((a && !b) || (!a && b)) {
        return false;
    }
    if (typeof(a)!='object' && typeof(b)!='object') {
        return a === b;
    }
    // Of course, we can do it use for in
    // Create arrays of property names
    var aProps = Object.getOwnPropertyNames(a);
    var bProps = Object.getOwnPropertyNames(b);
    // If number of properties is different,
    // objects are not equivalent
    if (aProps.length != bProps.length) {
        return false;
    }
    for (var i = 0; i < aProps.length; i++) {
        var propName = aProps[i];
        // If values of same property are not equal,
        // objects are not equivalent
        if (a[propName] !== b[propName]) {
            return false;
        }
    }
    // If we made it this far, objects
    // are considered equivalent
    return true;
}

//兼容浏览器console对象
//创建空console对象，避免JS报错
if(!window.console)  {
    var c = {};
    var funcs = ['assert', 'clear', 'count', 'debug', 'dir', 'dirxml',
        'error', 'exception', 'group', 'groupCollapsed', 'groupEnd',
        'info', 'log', 'markTimeline', 'profile', 'profileEnd',
        'table', 'time', 'timeEnd', 'timeStamp', 'trace', 'warn'];
    for(var i=0,l=funcs.length;i<l;i++) {
        var func = funcs[i];
        if(!c[func])
            c[func] = function(){};
    }
    window.console = c;
}



